<?php 

/**
 +----------------------------------------------+
 * PHP Version 5.2.6                            *
 +----------------------------------------------+
 * 功能说明：
 +----------------------------------------------+
 * @Author    ：九九                            *
 * @QQ        ：405494897                       *
 * @Email     ：xjiujiu@foxmail.com             *
 * @Copyright ：2011/11/05                      *
 * @version   ：                                *
 * @package   ：                                *
 +----------------------------------------------+ 
**/

define('NAME_MD5', 1);
define('NAME_BASE64', 2);
define('NAME_TIME', 3);
define('NAME_UUID', 4);

class UploadFile {
    protected $_fileInfo    = array();

    protected $_uploadDir   = '';
    
    protected $_fileTypes   = array();

    protected $_fileSize    = 0;

    protected $_error       = '';

    protected $_fileType    = '';

    protected $_uploadFileName      = '';

    protected $_targetFilePath = '';

    protected static $fileTypes     = array(
        'chm'=>array('application/octet-stream'), 
        'ppt'=>array('application/vnd.ms-powerpoint'), 
        'xls'=>array('application/vnd.ms-excel'), 
        'doc'=>array('application/msword'), 
        'exe'=>array('application/octet-stream'), 
        'rar'=>array('application/octet-stream'), 
        'js'=>array('javascript/js'), 
        'css'=>array('text/css'), 
        'hqx'=>array('application/mac-binhex40'), 
        'bin'=>array('application/octet-stream'), 
        'oda'=>array('application/oda'), 
        'pdf'=>array('application/pdf'), 
        'ai'=>array('application/postsrcipt'), 
        'eps'=>array('application/postsrcipt'), 
        'es'=>array('application/postsrcipt'), 
        'rtf'=>array('application/rtf'), 
        'mif'=>array('application/x-mif'), 
        'csh'=>array('application/x-csh'), 
        'dvi'=>array('application/x-dvi'), 
        'hdf'=>array('application/x-hdf'), 
        'nc'=>array('application/x-netcdf'), 
        'cdf'=>array('application/x-netcdf'), 
        'latex'=>array('application/x-latex'), 
        'ts'=>array('application/x-troll-ts'), 
        'src'=>array('application/x-wais-source'), 
        'zip'=>array('application/zip'), 
        'bcpio'=>array('application/x-bcpio'), 
        'cpio'=>array('application/x-cpio'), 
        'gtar'=>array('application/x-gtar'), 
        'shar'=>array('application/x-shar'), 
        'sv4cpio'=>array('application/x-sv4cpio'), 
        'sv4crc'=>array('application/x-sv4crc'), 
        'tar'=>array('application/x-tar'), 
        'ustar'=>array('application/x-ustar'), 
        'man'=>array('application/x-troff-man'), 
        'sh'=>array('application/x-sh'), 
        'tcl'=>array('application/x-tcl'), 
        'tex'=>array('application/x-tex'), 
        'texi'=>array('application/x-texinfo'), 
        'texinfo'=>array('application/x-texinfo'), 
        't'=>array('application/x-troff'), 
        'tr'=>array('application/x-troff'), 
        'roff'=>array('application/x-troff'), 
        'shar'=>array('application/x-shar'), 
        'me'=>array('application/x-troll-me'), 
        'ts'=>array('application/x-troll-ts'), 
        'gif'=>array('image/gif'), 
        'jpeg'=>array('image/pjpeg', 'image/jpeg'), 
        'jpg'=>array('image/pjpeg'), 
        'png'=>array('image/png'), 
        'bmp'=>array('image/bmp'), 
        'jpe'=>array('image/pjpeg'), 
        'ras'=>array('image/x-cmu-raster'), 
        'pbm'=>array('image/x-portable-bitmap'), 
        'ppm'=>array('image/x-portable-pixmap'), 
        'xbm'=>array('image/x-xbitmap'), 
        'xwd'=>array('image/x-xwindowdump'), 
        'ief'=>array('image/ief'), 
        'tif'=>array('image/tiff'), 
        'tiff'=>array('image/tiff'), 
        'pnm'=>array('image/x-portable-anymap'), 
        'pgm'=>array('image/x-portable-graymap'), 
        'rgb'=>array('image/x-rgb'), 
        'xpm'=>array('image/x-xpixmap'), 
        'txt'=>array('text/plain'), 
        'c'=>array('text/plain'), 
        'cc'=>array('text/plain'), 
        'h'=>array('text/plain'), 
        'html'=>array('text/html'), 
        'htm'=>array('text/html'), 
        'htl'=>array('text/html'), 
        'rtx'=> array('text/richtext'),
        'mp3' => array('application/octet-stream')
    );

    /**
     * 上传的执行动作
     * 里面包含有验证过程创建上传日期目录及上传的动作
     *
     * @access public
     * @param string $fileInfo 文件信息数组来自$_FILES
     * @param string $uploadDir 上传的目标位置
     * @param int $fileSize 上传文件的最大大小
     * @param array $fileTypes 上传文件允许的类型
     * @param int 上传文件名的变换方式md5,base64,time,uuid(1,2,3,4)
     *
     * @return boolean
     */
    public function __construct($fileInfo, $uploadDir, $fileTypes, $fileSize, $nameType = 3) {
        $this->_fileInfo    = $fileInfo;
        $this->_uploadDir   = $uploadDir;
        $this->_fileTypes   = $fileTypes;
        $this->_fileSize    = $fileSize * 1024 * 1024;
        $this->_nameType    = 3;
    }

    public function upload() {
        if(false === $this->verifyDir()) {
            $this->_error   = '保存文件目录无效，请确认！';
            return false;
        }
        if(false === $this->verifyFileType()) {
            $this->_error   = '文件类型不合法，请确认！';
            return false; 
        }
        if(false == $this->verifyFileSize()) {
            $this->_error   = '文件太大！';
            return false;
        }
        if(false === $this->createUploadDateDir()) {
            $this->_error   = '创建上传日期目录失败，请检查磁盘是否还有可用空间！';
            return false;
        }
        $this->_targetFilePath  = $this->genUploadFilePath();
        if(!move_uploaded_file($this->_fileInfo['tmp_name'], $this->_targetFilePath)) {
            $this->_error   = '文件上传失败，请检查是否还有可用的空间！';
            return false;
        }

        return true;
    }

    protected function verifyDir() {
        if(is_dir($this->_uploadDir) && is_writeable($this->_uploadDir)) {
            return true;
        }

        return false;
    }

    protected function verifyFileType() {
        foreach($this->_fileTypes as $type) {
            if(in_array($this->_fileInfo['type'], self::$fileTypes[$type])) {
                $this->_fileType    = $type;
                return true;
            }
        }

        return false;
    }

    protected function verifyFileSize() {
        if($this->_fileSize < $this->_fileInfo['size']) {
            return false;
        }

        return true;
    }

    protected function createUploadDateDir() {
        $date   = date("Y-m-d");
        $this->_uploadDir   .= '/' . date("Y-m-d");
        if(file_exists($this->_uploadDir)) {
           return true; 
        }
        if(!mkdir($this->_uploadDir)) {
            return false;
        }

        return true;
    }

    public function genUploadFilePath() {
        return $this->_uploadDir . '/' . $this->genUploadFileName() . $this->getFileFormat();
    }

    public function getUploadFilePath() {
        return $this->_targetFilePath;
    }

    protected function genUploadFileName() {
        switch($this->_nameType) {
        case NAME_MD5:
            $this->_uploadFileName  = md5($this->getFileName());
            break;
        case NAME_BASE64:
            $this->_uploadFileName  = base64_encode($this->getFileName());
            break;
        case NAME_TIME:
            $this->_uploadFileName  = date("YmdHms") . mktime();
            break;
        case NAME_UUID:
            $this->_uploadFileName  = LittleTools::getUUID();
            break;
        default:
            $this->_uploadFileName  = $this->getFileName();
            break;
        }

        return $this->_uploadFileName;
    }

    protected function getFileFormat() {
        return substr($this->_fileInfo['name'],strrpos($this->_fileInfo['name'], '.'));
    }

    protected function getFileName() {
        return substr($this->_fileInfo['name'], 0, strrpos($this->_fileInfo['name'], '.'));
    }

    public function setFileInfo($fileInfo) {
        $this->_fileInfo    = $fileInfo;
    }

    public function setFileTypes($fileTypes) {
        $this->_fileTypes   = $fileTypes;
    }

    public function setFileSize() {
        $this->_fileSize    = $fileSize;
    }

    public function setNameType($nameType) {
        $this->_nameType    = $nameType;
    }

    public function getError() {
        return $this->_error;
    }

    public function getFileType() {
        return $this->_fileType;
    }

    public function getUploadFileName() {
        return $this->_uploadFileName;
    }

}


?>
